package com.gopay.bis.common.util;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.gopay.bis.common.util.constants.BisPayConstants;

/**
 * BIS支付请求报文验证类
 * 
 * @author wanggang
 * 
 */
public class BisPayCheckUtils {

	private static final Pattern P_PLATFORMID = Pattern.compile("^[\\da-zA-Z]{1,10}$");

	private static final Pattern P_URL = Pattern
			.compile("^http[s]?:\\/\\/([\\w-]+\\.)+[\\w-]+([\\w-./?%&=]*)?$");

	private static final Pattern P_ORDERID = Pattern.compile("^[\\da-zA-Z]{1,30}$");

	/**
	 * 日期检查. yyyymmdd 年：1600－9999 会检查闰月.
	 */
	public static final Pattern P_DATE_ONLY_NUMBER = Pattern
			.compile("^((1[6-9]|[2-9]\\d)?\\d{2})(((0[13578]|1[02])31)|((0[1,3-9]|1[0-2])(29|30)))$|"
					+ "^(((1[6-9]|[2-9]\\d)?(0[48]|[2468][048]|[13579][26])|"
					+ "((16|[2468][048]|[3579][26])00)))(0229)$|^((1[6-9]|[2-9]\\d)?\\d{2})((0[1-9])|(1[0-2]))(0[1-9]|1\\d|2[0-8])$");

	/**
	 * 6位时间检查. 时：00－23 分：00－59 秒：00－59.
	 */
	public static final Pattern P_TIME = Pattern
			.compile("^(([0-1][0-9])|(2[0-3]))([0-5][0-9])([0-5][0-9])$");

	private static final Pattern P_AMOUNT = Pattern.compile("^((([1-9]{1}\\d{0,9}))|([0]{1}))((\\.(\\d){0,2}))?$");

	private static final Pattern P_BANK = Pattern.compile("^[A-Za-z]{1,10}$");

	private static final Pattern P_USERIP = Pattern
			.compile("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
					+ "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");

	private static final Pattern P_EXPAND = Pattern.compile("^[\\da-zA-Z]{1,400}$");

	private static final Pattern P_EXPIRETIME = Pattern.compile("^\\d{1,10}$");

	private static final Pattern P_SIGN = Pattern.compile("^[\\da-zA-Z]{1,500}$");
	
    private static Set<String> bankSet = new HashSet<String>();
    
    static {
    	
    	bankSet.add("ABC");
    	bankSet.add("BOBJ");
    	bankSet.add("BOC");
    	bankSet.add("BOCOM");    	
    	bankSet.add("BOS");
    	bankSet.add("CCB");
    	bankSet.add("CEB");
    	bankSet.add("CIB");
    	bankSet.add("CITIC");
    	bankSet.add("CMB");
    	bankSet.add("CMBC");
    	bankSet.add("GDB");
    	bankSet.add("HXBC");
    	bankSet.add("ICBC");
    	bankSet.add("NBCB");
    	bankSet.add("NJCB");
    	bankSet.add("PAB");
    	bankSet.add("PSBC");
    	bankSet.add("SHRCB");
    	bankSet.add("SPDB");
    	bankSet.add("SRCB");
    	bankSet.add("TCCB");
    	bankSet.add("TBANK");
    }
	
	public static boolean checkPlatformID(String platformID) {
		if (platformID == null)
			return false;
		Matcher m = P_PLATFORMID.matcher(platformID);
		return m.matches();
	}

	public static boolean checkUrl(String url) {
		if (url == null)
			return false;
		Matcher m = P_URL.matcher(url);
		return m.matches();
	}

	public static boolean checkOrderID(String orderID) {
		if (orderID == null)
			return false;
		Matcher m = P_ORDERID.matcher(orderID);
		return m.matches();
	}

	public static boolean checkExternalOrderID(String gopayOrderId) {
		String isExternal = gopayOrderId.substring(0, 2);
		if(isExternal.equals(BisPayConstants.GOPAY_ORDER) 
				|| isExternal.equals(BisPayConstants.THIRDPARTY_PLATFORM) 
				|| isExternal.equals(BisPayConstants.INDEPENDENT_MERCHANTS)){
			return true;
		}else{
			return false;
		}
	}
	
	public static boolean checkGoPayOrderID(String gopayOrderId) {
		String isExternal = gopayOrderId.substring(0, 2);
		if(isExternal.equals(BisPayConstants.GOPAY_ORDER)){
			return true;
		}else{
			return false;
		}
	}
	
	public static boolean checkPlatformDate(String platformDate) {
		if (platformDate == null)
			return false;
		Matcher m1 = P_DATE_ONLY_NUMBER.matcher(platformDate.substring(0, 8));
		Matcher m2 = P_TIME.matcher(platformDate.substring(8));
		return m1.matches() && m2.matches();
	}
	
	public static boolean checkAmount(String amount) {
		if (amount == null)
			return false;
		Matcher m = P_AMOUNT.matcher(amount);
		return m.matches();
	}

	public static boolean checkBankName(String bank) {
		if (bank == null)
			return false;
		Matcher m = P_BANK.matcher(bank);
		return m.matches();
	}
	
	public static boolean checkBank(String bank) {		
		return bankSet.contains(bank);
	}

	public static boolean checkUserIP(String userIP) {
		if (userIP == null)
			return false;
		Matcher m = P_USERIP.matcher(userIP);
		return m.matches();
	}

	public static boolean checkExpand(String expand) {
		if (expand == null)
			return false;
		Matcher m = P_EXPAND.matcher(expand);
		return m.matches();
	}

	public static boolean checkExpireTime(String expireTime) {
		if (expireTime == null)
			return false;
		Matcher m = P_EXPIRETIME.matcher(expireTime);
		return m.matches();
	}
	
	public static boolean checkSign(String Sign) {
		if (Sign == null)
			return false;
		Matcher m = P_SIGN.matcher(Sign);
		return m.matches();
	}

	public static void main(String[] args) {
		System.out.println(checkPlatformID("GFB"));
		System.out.println(checkPlatformID("GFB1234567"));
		System.out.println(checkUrl("GFB1234567"));
		System.out.println(checkUrl("http://fdsafa.com/fdasfa.qq"));
		System.out.println(checkOrderID("01234567890123456789012345678a1"));
		System.out.println(checkOrderID("01234567890123456789012345678a"));
		System.out.println(checkPlatformDate("201401311121212"));
		System.out.println(checkPlatformDate("20140131235959"));
		System.out.println(checkAmount("99999999999.1"));
		System.out.println(checkAmount("999999999999"));
		System.out.println(checkBank("ABC110"));
		System.out.println(checkBank("CCB"));
		System.out.println(checkUserIP("256.255.255.1"));
		System.out.println(checkUserIP("192.168.1.1"));
		System.out.println(checkExpand(""));
		System.out.println(checkExpand("CCB"));
		System.out.println(checkExpireTime("ABC110"));
		System.out.println(checkExpireTime("1234567890"));
	}

}
